#include <arpa/inet.h>
#include <QDir>
#include <QFile>
#include <QDebug>
#include <QMenu>
#include <QAction>
#include <QPushButton>
#include <QHBoxLayout>
#include <QMessageBox>
#include <QFileDialog>
#include <QInputDialog>

#include "request.h"
#include "mainwindow.h"
#include "ui_mainwindow.h"

static quint16 DEFAULT_PORT = 69;
static QString DEFAULT_TABS = "1,2,3,4,5,6,7,8";
static QString DEFAULT_DIR = QDir::homePath().append("/Desktop");

void MainWindow::initConfig()
{
    mSetting = new QSettings("TFTPServer", "config");

    if (!mSetting->contains("init"))
    {
        mSetting->setValue("init", "1");
        mSetting->setValue("tabs", DEFAULT_TABS);
        mSetting->setValue("select", "1");

        foreach (QString name, DEFAULT_TABS.split(","))
        {
            mSetting->beginGroup(name);
            mSetting->setValue("type", "real");
            mSetting->setValue("dir", DEFAULT_DIR);
            mSetting->endGroup();
        }
    }
}

void MainWindow::initServer()
{
    mSocket = new QUdpSocket(this);

    if (!mSocket->bind(QHostAddress::AnyIPv4, DEFAULT_PORT))
    {
        QMessageBox::information(NULL, "TFTP Server",
                                "Could not bin socket. Address and port are already in use.",
                                QMessageBox::Close, QMessageBox::Close);
        return;
    }

    connect(mSocket, SIGNAL(readyRead()), this, SLOT(handTFTPRequest()));
}

void MainWindow::handTFTPRequest()
{
    char *p;
    int rrid;
    Request *req;
    Request::Message msg;
    Request::OpCode oc;
    Request::TransMode tm;
    QHostAddress address;
    quint16 port;
    QWidget *root;
    QString filename;
    QString filepath;
    QLineEdit *realPathEdit;
    QTableWidget *virtualTableWidget;
    QTableWidgetItem *tableWidgetItem;

    while (mSocket->hasPendingDatagrams()) {
        /* 1. read data */
        if (mSocket->readDatagram((char *)&msg, sizeof(msg), &address, &port) < 0) {
            qDebug() << "Failed to read message";
            continue;
        }

        /* 2. opcode check */
        if (msg.opcode == ntohs(Request::OC_RRQ)) {
            oc = Request::OC_RRQ;
        } else if (msg.opcode == ntohs(Request::OC_WRQ)) {
            oc = Request::OC_WRQ;
        } else {
            qDebug() << "Invalid opcode " << ntohs(msg.opcode);
            continue;
        }

        /* 3. transfer mode check */
        filename = QString(msg.request.filename_and_mode);
        p = msg.request.filename_and_mode + strlen(msg.request.filename_and_mode) + 1;
        if (!strcmp(p, "netascii")) {
            tm = Request::TM_ASCII;
        } else if (!strcmp(p, "octet")) {
            tm = Request::TM_OCTET;
        } else {
            qDebug() << "Invalid transfer mode " << tm;
            continue;
        }

        /* 4. get file path */
        root = ui->tabWidget->currentWidget();
        realPathEdit = root->findChild<QLineEdit *>(QString::fromUtf8("realPathEdit"));
        virtualTableWidget = root->findChild<QTableWidget *>(QString::fromUtf8("virtualTableWidget"));

        if (!realPathEdit->isVisible()) {
            for (int i = 0; i < virtualTableWidget->rowCount(); i++) {
                tableWidgetItem = virtualTableWidget->item(i, 0);
                if (tableWidgetItem) {
                    if (tableWidgetItem->text() == filename) {
                        filepath = virtualTableWidget->item(i, 1)->text();
                    }
                }
            }
        } else {
            filepath = realPathEdit->text() + "/" + filename;
        }

        /* 5. get available result rowid */
        rrid = -1;
        for (int i = 0; i < ui->tableWidget->rowCount(); i++) {
            tableWidgetItem = ui->tableWidget->item(i, 0);
            if (!tableWidgetItem || tableWidgetItem->text().isEmpty()) {
                rrid = i;
                break;
            }
        }

        if (rrid < 0) {
            rrid = ui->tableWidget->rowCount() + 1;
            ui->tableWidget->setRowCount(rrid);
        }

        /* 6. status */
        ui->tableWidget->setItem(rrid, 0, new QTableWidgetItem(address.toString()));
        ui->tableWidget->setItem(rrid, 2, new QTableWidgetItem("<< " + filename));
        ui->tableWidget->setItem(rrid, 3, new QTableWidgetItem("0"));
        ui->tableWidget->setItem(rrid, 4, new QTableWidgetItem("0"));

        if (QFile::exists(filepath)) {
            ui->tableWidget->setItem(rrid, 1, new QTableWidgetItem("Downloading"));
            ui->tableWidget->setItem(rrid, 5, new QTableWidgetItem(filepath));
        } else {
            ui->tableWidget->setItem(rrid, 1, new QTableWidgetItem("Denied"));
            ui->tableWidget->setItem(rrid, 5, new QTableWidgetItem("No file found"));
        }

        /* 7. start handle request */
        req = new Request(this, filename, oc, tm);
        req->setRrid(rrid);
        req->setFilePath(filepath);
        req->setDestination(address, port);

        connect(req, SIGNAL(progress(int, qint64, qint64)),
                this, SLOT(on_tftp_progress(int, qint64, qint64)));

        req->start();
    }
}

QWidget *MainWindow::createTabView()
{
    QWidget *tabWidgetMain;
    QGridLayout *gridLayout_2;
    QLineEdit *realPathEdit;
    QPushButton *realBrowButton;
    QTableWidget *virtualTableWidget;
    QVBoxLayout *verticalLayout;
    QPushButton *virtualAddButton;
    QPushButton *virtualClearButton;
    QPushButton *virtualDelButton;

    QSizePolicy sizePolicy1(QSizePolicy::Preferred, QSizePolicy::Preferred);
    sizePolicy1.setHorizontalStretch(0);
    sizePolicy1.setVerticalStretch(0);

    tabWidgetMain = new QWidget();
    tabWidgetMain->setObjectName(QString::fromUtf8("tabWidgetMain"));

    QSizePolicy sizePolicy3(QSizePolicy::Minimum, QSizePolicy::Minimum);
    sizePolicy3.setHorizontalStretch(1);
    sizePolicy3.setVerticalStretch(1);
    sizePolicy3.setHeightForWidth(tabWidgetMain->sizePolicy().hasHeightForWidth());

    tabWidgetMain->setSizePolicy(sizePolicy3);
    gridLayout_2 = new QGridLayout(tabWidgetMain);
    gridLayout_2->setObjectName(QString::fromUtf8("gridLayout_2"));
    realPathEdit = new QLineEdit(tabWidgetMain);
    realPathEdit->setObjectName(QString::fromUtf8("realPathEdit"));
    sizePolicy1.setHeightForWidth(realPathEdit->sizePolicy().hasHeightForWidth());
    realPathEdit->setSizePolicy(sizePolicy1);
    realPathEdit->setStyleSheet(QString::fromUtf8("background-color:#FFFFFF;"));

    gridLayout_2->addWidget(realPathEdit, 0, 0, 1, 1);

    realBrowButton = new QPushButton(tabWidgetMain);
    realBrowButton->setObjectName(QString::fromUtf8("realBrowButton"));
    QSizePolicy sizePolicy4(QSizePolicy::Fixed, QSizePolicy::Preferred);
    sizePolicy4.setHorizontalStretch(0);
    sizePolicy4.setVerticalStretch(0);
    sizePolicy4.setHeightForWidth(realBrowButton->sizePolicy().hasHeightForWidth());
    realBrowButton->setSizePolicy(sizePolicy4);

    gridLayout_2->addWidget(realBrowButton, 0, 1, 1, 1);

    virtualTableWidget = new QTableWidget(tabWidgetMain);
    if (virtualTableWidget->columnCount() < 2)
        virtualTableWidget->setColumnCount(2);
    QTableWidgetItem *__qtablewidgetitem7 = new QTableWidgetItem();
    virtualTableWidget->setHorizontalHeaderItem(0, __qtablewidgetitem7);
    QTableWidgetItem *__qtablewidgetitem8 = new QTableWidgetItem();
    virtualTableWidget->setHorizontalHeaderItem(1, __qtablewidgetitem8);
    if (virtualTableWidget->rowCount() < 6)
        virtualTableWidget->setRowCount(5);
    QTableWidgetItem *__qtablewidgetitem9 = new QTableWidgetItem();
    virtualTableWidget->setVerticalHeaderItem(0, __qtablewidgetitem9);
    QTableWidgetItem *__qtablewidgetitem10 = new QTableWidgetItem();
    virtualTableWidget->setVerticalHeaderItem(1, __qtablewidgetitem10);
    QTableWidgetItem *__qtablewidgetitem11 = new QTableWidgetItem();
    virtualTableWidget->setVerticalHeaderItem(2, __qtablewidgetitem11);
    QTableWidgetItem *__qtablewidgetitem12 = new QTableWidgetItem();
    virtualTableWidget->setVerticalHeaderItem(3, __qtablewidgetitem12);
    QTableWidgetItem *__qtablewidgetitem13 = new QTableWidgetItem();
    virtualTableWidget->setVerticalHeaderItem(4, __qtablewidgetitem13);
    virtualTableWidget->setObjectName(QString::fromUtf8("virtualTableWidget"));
    virtualTableWidget->setStyleSheet(QString::fromUtf8("background-color:#FFFFFF;"));
    virtualTableWidget->setSizeAdjustPolicy(QAbstractScrollArea::AdjustToContents);
    virtualTableWidget->setSelectionMode(QAbstractItemView::NoSelection);
    virtualTableWidget->setSelectionBehavior(QAbstractItemView::SelectRows);

    virtualTableWidget->setAlternatingRowColors(false);
    virtualTableWidget->setShowGrid(true);
    virtualTableWidget->setGridStyle(Qt::SolidLine);
    virtualTableWidget->setWordWrap(true);
    virtualTableWidget->setCornerButtonEnabled(true);
    virtualTableWidget->horizontalHeader()->setMinimumSectionSize(40);
    virtualTableWidget->horizontalHeader()->setDefaultSectionSize(150);
    virtualTableWidget->horizontalHeader()->setStretchLastSection(true);
    virtualTableWidget->verticalHeader()->setVisible(false);
    virtualTableWidget->verticalHeader()->setMinimumSectionSize(18);
    virtualTableWidget->verticalHeader()->setDefaultSectionSize(18);
    virtualTableWidget->verticalHeader()->setHighlightSections(true);
    virtualTableWidget->verticalHeader()->setStretchLastSection(false);

    gridLayout_2->addWidget(virtualTableWidget, 1, 0, 1, 1);

    verticalLayout = new QVBoxLayout();
    verticalLayout->setSpacing(6);
    verticalLayout->setObjectName(QString::fromUtf8("verticalLayout"));
    virtualAddButton = new QPushButton(tabWidgetMain);
    virtualAddButton->setObjectName(QString::fromUtf8("virtualAddButton"));

    verticalLayout->addWidget(virtualAddButton);

    virtualClearButton = new QPushButton(tabWidgetMain);
    virtualClearButton->setObjectName(QString::fromUtf8("virtualClearButton"));

    verticalLayout->addWidget(virtualClearButton);

    virtualDelButton = new QPushButton(tabWidgetMain);
    virtualDelButton->setObjectName(QString::fromUtf8("virtualDelButton"));

    realBrowButton->setText(QApplication::translate("MainWindow", "Browser", nullptr));
    __qtablewidgetitem7->setText(QApplication::translate("MainWindow", "Name", nullptr));
    __qtablewidgetitem8->setText(QApplication::translate("MainWindow", "File Path", nullptr));
    virtualAddButton->setText(QApplication::translate("MainWindow", "Add", nullptr));
    virtualClearButton->setText(QApplication::translate("MainWindow", "Clear", nullptr));
    virtualDelButton->setText(QApplication::translate("MainWindow", "Delete", nullptr));

    verticalLayout->addWidget(virtualDelButton);
    gridLayout_2->addLayout(verticalLayout, 1, 1, 1, 1);

    connect (realBrowButton, SIGNAL(clicked()), this, SLOT(on_browButton_clicked()));
    connect (virtualAddButton, SIGNAL(clicked()), this, SLOT(on_virtual_add_clicked()));
    connect (virtualClearButton, SIGNAL(clicked()), this, SLOT(on_virtual_clear_clicked()));
    connect (virtualDelButton, SIGNAL(clicked()), this, SLOT(on_virtual_del_clicked()));

    return tabWidgetMain;
}

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent), ui(new Ui::MainWindow)
{
    initConfig();
    initServer();

    ui->setupUi(this);

    /* add tabs */
    ui->tabWidget->clear();
    foreach (QString name, mSetting->value("tabs").toString().split(",")) {
        ui->tabWidget->addTab(createTabView(), name);
    }

    /* add ">>" tab */
    ui->tabWidget->addTab(createTabView(), ">>");

    /* last selected tab */
    QString sel = mSetting->value("select").toString();
    for (int i = 0; i < ui->tabWidget->count(); i++) {
        if (ui->tabWidget->tabText(i) == sel) {
            ui->tabWidget->setCurrentIndex(i);
            break;
        }
    }
}

MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::on_browButton_clicked()
{
    QWidget *tab = qobject_cast<QWidget *>(sender()->parent());
    QLineEdit *lineEdit = tab->findChild<QLineEdit *>(QString::fromUtf8("realPathEdit"));
    QString dir = QFileDialog::getExistingDirectory(NULL, tr("Choose Directory"), lineEdit->text());

    if (dir.length() > 0)
    {
        mSetting->beginGroup(tab->objectName());
        mSetting->setValue("dir", dir);
        mSetting->endGroup();

        lineEdit->setText(dir);
    }
}

void MainWindow::on_virtual_add_clicked()
{
    int idx = -1;
    QFileInfo *file;
    QTableWidget *tableWidget;
    QTableWidgetItem *tableWidgetItem;
    QString filename = QFileDialog::getOpenFileName();
    QWidget *root = ui->tabWidget->widget(ui->tabWidget->currentIndex());
    QString label = ui->tabWidget->tabText(ui->tabWidget->currentIndex());

    file = new QFileInfo(filename);
    if (file->exists())
    {
        tableWidget = root->findChild<QTableWidget *>(QString::fromUtf8("virtualTableWidget"));

        /* exist check and find usable row */
        for (int i = 0; i < tableWidget->rowCount(); i++)
        {
            tableWidgetItem = tableWidget->item(i, 0);
            if (!tableWidgetItem || tableWidgetItem->text().isEmpty())
            {
                idx = i;
                break;
            }

            if (tableWidgetItem->text() == file->fileName())
            {
                // exist : TODO
                return;
            }
        }

        /* add new */
        if (idx == -1)
        {
            idx = tableWidget->rowCount();
            tableWidget->setRowCount(idx + 1);
        }

        tableWidget->setItem(idx, 0, new QTableWidgetItem(file->fileName()));
        tableWidget->setItem(idx, 1, new QTableWidgetItem(file->absoluteFilePath()));

        /* update setting */
        mSetting->beginGroup(label);
        idx = mSetting->beginReadArray("varray");
        mSetting->endArray();
        mSetting->beginWriteArray("varray");
        mSetting->setArrayIndex(idx);
        mSetting->setValue("name", file->fileName());
        mSetting->setValue("path", file->absoluteFilePath());
        mSetting->endArray();
        mSetting->endGroup();
    }
}

void MainWindow::on_virtual_clear_clicked()
{
    int r;
    QWidget *root;
    QString label;
    QTableWidget *tableWidget;

    r = QMessageBox::question(NULL, "Confirm", "Clear current file list?",
                                  QMessageBox::Ok|QMessageBox::Cancel, QMessageBox::Ok);
    if (r == QMessageBox::Cancel) {
        return;
    }

    root = ui->tabWidget->widget(ui->tabWidget->currentIndex());
    label = ui->tabWidget->tabText(ui->tabWidget->currentIndex());
    tableWidget = root->findChild<QTableWidget *>(QString::fromUtf8("virtualTableWidget"));

    /* resize table */
    tableWidget->setRowCount(0);
    tableWidget->setRowCount(5);

    /* update setting */
    mSetting->beginGroup(label);
    mSetting->beginReadArray("varray");
    mSetting->remove("");
    mSetting->endArray();
    mSetting->endGroup();
}

void MainWindow::on_virtual_del_clicked()
{
    int r, rowId;
    QWidget *root;
    QString label;
    QTableWidget *tableWidget;

    r = QMessageBox::question(NULL, "Confirm", "Remove selected item or items?",
                                  QMessageBox::Ok|QMessageBox::Cancel, QMessageBox::Ok);
    if (r == QMessageBox::Cancel) {
        return;
    }

    root = ui->tabWidget->widget(ui->tabWidget->currentIndex());
    label = ui->tabWidget->tabText(ui->tabWidget->currentIndex());
    tableWidget = root->findChild<QTableWidget *>(QString::fromUtf8("virtualTableWidget"));
    rowId = tableWidget->currentRow();

    if (rowId < 0)
        return;

    if (!tableWidget->item(rowId, 0))
        return;

    /* delete table item */
    tableWidget->removeRow(rowId);
    if (tableWidget->rowCount() < 5)
        tableWidget->setRowCount(5);

    /* update setting */
    mSetting->beginGroup(label);
    mSetting->beginWriteArray("varray");
    mSetting->remove("");
    mSetting->endArray();
    mSetting->beginWriteArray("varray");

    for (int i = 0; i < tableWidget->rowCount(); i++)
    {
        if (!tableWidget->item(i, 0))
            break;

        mSetting->setArrayIndex(i);
        mSetting->setValue("name", tableWidget->item(i, 0)->text());
        mSetting->setValue("path", tableWidget->item(i, 1)->text());
    }

    mSetting->endArray();
    mSetting->endGroup();
}

void MainWindow::on_tabWidget_tabBarClicked(int index)
{
    QString label;

    /* last tab clicked: add a new tab */
    if (index == (ui->tabWidget->count() - 1))
    {
        label = QString::number(index + 1);

        ui->tabWidget->setTabText(index, label);
        ui->tabWidget->setCurrentIndex(index);

        /* add group */
        mSetting->beginGroup(label);
        mSetting->setValue("type", "real");
        mSetting->setValue("dir", DEFAULT_DIR);
        mSetting->endGroup();

        /* update "tabs" */
        mSetting->setValue("focus", label);
        mSetting->setValue("tabs", mSetting->value("tabs").toString().append(",").append(label));

        ui->tabWidget->addTab(createTabView(), ">>");
    }

    mSetting->setValue("select", ui->tabWidget->tabText(index));
}

void MainWindow::on_tab_rename_triggered()
{
    bool ok;
    QStringList keys;
    QStringList tabs;
    QTabBar *tabBar = ui->tabWidget->tabBar();
    QString oLabel = tabBar->tabText(tabBar->currentIndex());

    QString nLabel = QInputDialog::getText(NULL, tr("Rename"), tr("New label:"),
                                           QLineEdit::Normal, oLabel, &ok);
    if (ok && !nLabel.isEmpty() && nLabel != oLabel) {
        /* get all old keys */
        mSetting->beginGroup(oLabel);
        keys = mSetting->allKeys();
        mSetting->endGroup();

        /* gen new group */
        foreach (QString key, keys) {
            mSetting->setValue(nLabel + "/" + key, mSetting->value(oLabel + "/" + key));
        }

        /* del old group */
        mSetting->beginGroup(oLabel);
        mSetting->remove("");
        mSetting->endGroup();

        /* update tabs */
        tabs = mSetting->value("tabs").toString().split(",");
        tabs.replace(tabs.indexOf(oLabel), nLabel);
        mSetting->setValue("tabs", tabs.join(","));

        /* select */
        mSetting->setValue("select", nLabel);

        tabBar->setTabText(tabBar->currentIndex(), nLabel);
    }
}

void MainWindow::on_tab_delete_triggered()
{
    QStringList tabs;
    QTabBar *tabBar = ui->tabWidget->tabBar();
    QString label = tabBar->tabText(tabBar->currentIndex());

    if (tabBar->count() > 2)
    {
        /* del old group */
        mSetting->beginGroup(label);
        mSetting->remove("");
        mSetting->endGroup();

        /* update tabs */
        tabs = mSetting->value("tabs").toString().split(",");
        tabs.removeAt(tabs.indexOf(label));
        mSetting->setValue("tabs", tabs.join(","));

        tabBar->removeTab(tabBar->currentIndex());
    }
}

void MainWindow::on_tab_real_triggered()
{
    QTabBar *tabBar = ui->tabWidget->tabBar();
    QString label = tabBar->tabText(ui->tabWidget->currentIndex());

    mSetting->beginGroup(label);
    mSetting->setValue("type", "real");
    mSetting->endGroup();

    on_tabWidget_currentChanged(ui->tabWidget->currentIndex());
}

void MainWindow::on_tab_virtual_triggered()
{
    QTabBar *tabBar = ui->tabWidget->tabBar();
    QString label = tabBar->tabText(tabBar->currentIndex());

    mSetting->beginGroup(label);
    mSetting->setValue("type", "virtual");
    mSetting->endGroup();

    on_tabWidget_currentChanged(ui->tabWidget->currentIndex());
}

void MainWindow::on_tabWidget_customContextMenuRequested(const QPoint &pos)
{
    QMenu *menu;
    QAction *action;
    QTabBar *tabBar = ui->tabWidget->tabBar();

    if (tabBar->tabAt(pos) == tabBar->currentIndex())
    {
        menu = new QMenu(NULL);

        action = new QAction("Rename", menu);
        connect (action, SIGNAL(triggered()), this, SLOT(on_tab_rename_triggered()));
        menu->addAction(action);

        action = new QAction("Delete", menu);
        connect (action, SIGNAL(triggered()), this, SLOT(on_tab_delete_triggered()));
        menu->addAction(action);

        menu->addSeparator();

        action = new QAction("Real Folder", menu);
        connect (action, SIGNAL(triggered()), this, SLOT(on_tab_real_triggered()));
        menu->addAction(action);

        action = new QAction("Virtual Folder", menu);
        connect (action, SIGNAL(triggered()), this, SLOT(on_tab_virtual_triggered()));
        menu->addAction(action);

        menu->move(cursor().pos());
        menu->show();
    }
}

void MainWindow::on_tabWidget_currentChanged(int index)
{
    int size;
    QLineEdit *realPathEdit;
    QTableWidget *virtualTableWidget;
    QString label = ui->tabWidget->tabText(index);
    QWidget *root = ui->tabWidget->widget(index);

    if (index >= 0)
    {
        mSetting->beginGroup(label);

        /* ui */
        if (mSetting->value("type").toString() == QString::fromUtf8("virtual"))
        {
            root->findChild<QLineEdit *>(QString::fromUtf8("realPathEdit"))->hide();
            root->findChild<QPushButton *>(QString::fromUtf8("realBrowButton"))->hide();

            root->findChild<QTableWidget *>(QString::fromUtf8("virtualTableWidget"))->show();
            root->findChild<QPushButton *>(QString::fromUtf8("virtualAddButton"))->show();
            root->findChild<QPushButton *>(QString::fromUtf8("virtualClearButton"))->show();
            root->findChild<QPushButton *>(QString::fromUtf8("virtualDelButton"))->show();

            ui->tabWidget->setMaximumSize(QSize(1200, 160));
        }
        else
        {
            root->findChild<QLineEdit *>(QString::fromUtf8("realPathEdit"))->show();
            root->findChild<QPushButton *>(QString::fromUtf8("realBrowButton"))->show();
            root->findChild<QTableWidget *>(QString::fromUtf8("virtualTableWidget"))->hide();
            root->findChild<QPushButton *>(QString::fromUtf8("virtualAddButton"))->hide();
            root->findChild<QPushButton *>(QString::fromUtf8("virtualClearButton"))->hide();
            root->findChild<QPushButton *>(QString::fromUtf8("virtualDelButton"))->hide();
            ui->tabWidget->setMaximumSize(QSize(1200, 75));
        }

        /* data */
        realPathEdit = root->findChild<QLineEdit *>(QString::fromUtf8("realPathEdit"));
        realPathEdit->setText(mSetting->value("dir").toString());

        virtualTableWidget = root->findChild<QTableWidget *>(QString::fromUtf8("virtualTableWidget"));
        virtualTableWidget->setRowCount(0);

        size = mSetting->beginReadArray("varray");
        for (int i = 0; i < size; i++)
        {
            mSetting->setArrayIndex(i);
            virtualTableWidget->setRowCount(i + 1);
            virtualTableWidget->setItem(i, 0, new QTableWidgetItem(mSetting->value("name").toString()));
            virtualTableWidget->setItem(i, 1, new QTableWidgetItem(mSetting->value("path").toString()));
        }
        mSetting->endArray();

        if (virtualTableWidget->rowCount() < 5)
            virtualTableWidget->setRowCount(5);

        mSetting->endGroup();
    }
}

void MainWindow::on_tftp_progress(int rowid, qint64 trans, qint64 total)
{
    qDebug() << rowid << "|" << trans << "|" << total;

    // Aborted|Completed|Denied|Downloading

    ui->tableWidget->setItem(rowid, 3, new QTableWidgetItem(QString::number(trans)));
    ui->tableWidget->setItem(rowid, 4, new QTableWidgetItem(QString::number(trans/total*100)));
}
